// This file is a part of ChaosDB.
// Copyright (C) 2012 ChaoJianPeng
// email:chaojianpeng@gmail.com
//
// ChaosDB is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// ChaosDB is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

/*
 * bdb_api.cpp
 *
 *  Created on: 2012-3-29
 *      Author: chao
 */

#include <bdb.h>
#include <pthread.h>
#include "bdb_api.h"
#include "logger.h"
#include "cmalloc.h"
#include <stdlib.h>
#include <string.h>

const char DATA_STORE[] = "data.db";
const char DATA_BACKUP[] = "datat_bak.db";

DB *dbp, *bakdb;
int stackNum = 0;

void initDBT(DBT* dbt) {
	memset(dbt, 0, sizeof(DBT));
}

void bdbInit() {
	systemLogger("Berkeley DB Init.");
	db_create(&dbp, NULL, 0);
	u_int32_t flags = DB_CREATE;
	dbp->open(dbp, NULL, DATA_STORE, NULL, DB_HASH, flags, 0);
}

DB* getDb(){
	return dbp;
}

void* bdbRead(char* key, int keyLen) {
	DBT bdbKey, data;
	void* res;

	initDBT(&bdbKey);
	initDBT(&data);
	bdbKey.data = key;
	bdbKey.size = keyLen + 1;

	dbp->get(dbp, NULL, &bdbKey, &data, 0);

	res = cmalloc(data.size);
	memcpy(res, data.data, data.size);

	return res;
}

void bdbWrite(char* key, int keyLen, void* value, int valueLen) {
	DBT bdbKey, data;
	initDBT(&bdbKey);
	initDBT(&data);
	bdbKey.data = key;
	bdbKey.size = keyLen + 1;
	data.data = value;
	data.size = valueLen;

	dbp->put(dbp, NULL, &bdbKey, &data, 0);
	if (++stackNum > 100) {
		dbp->sync(dbp, 0);
	}
}

void bdbDelete(char* key, int keyLen) {
	DBT bdbKey;

	initDBT(&bdbKey);
	bdbKey.data = key;
	bdbKey.size = keyLen + 1;

	dbp->del(dbp, NULL, &bdbKey, 0);
}

void bdbBakInit() {
	systemLogger("Bak Init.");
	db_create(&dbp, NULL, 0);
	u_int32_t flags = DB_CREATE;
	bakdb->open(bakdb, NULL, DATA_STORE, NULL, DB_HASH, flags, 0);
}

void bdbBak(char* key, int keyLen, void* value, int valueLen) {
	DBT bdbKey, data;
	initDBT(&bdbKey);
	initDBT(&data);
	bdbKey.data = key;
	bdbKey.size = keyLen + 1;
	data.data = value;
	data.size = valueLen;
}

void bdbBakEnd() {
	bakdb->close(bakdb, 0);
}
